package com.example.shushiyunsst.fragment.main.mine.child

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.Handler
import android.provider.Settings
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
import com.example.library_common.bean.UpDataVersionBean
import com.example.library_common.global.AppGlobals
import com.example.library_common.utils.FileProviderHelper
import com.example.library_common.utils.FileUtil
import com.example.shushiyunsst.BuildConfig
import com.example.shushiyunsst.MyApp
import com.example.shushiyunsst.R
import com.lxj.xpopup.core.CenterPopupView
import com.permissionx.guolindev.PermissionX
import okhttp3.*
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.util.concurrent.TimeUnit

class UpDataVersionPop(context: Context) : CenterPopupView(context) {


    private var filePath: String = ""

    override fun getImplLayoutId(): Int {
        return R.layout.up_data_version_pop
    }

    private lateinit var mProgressBar: ProgressBar
    private lateinit var upDataNow: TextView

    private var mVersionBean: UpDataVersionBean? = null

    private var okHttpClient: OkHttpClient? = null

    private var isDownloading = false //下载的标志位


    private val permissions = arrayOf(
        Manifest.permission.WRITE_EXTERNAL_STORAGE,

        Manifest.permission.READ_EXTERNAL_STORAGE,

        )

    private var target: Fragment? = null

    fun setTarget(target: Fragment) {
        this.target = target
    }

    fun setVersionBean(mVersionBean: UpDataVersionBean?) {
        this.mVersionBean = mVersionBean
    }

    private val handles = Handler()

    override fun onCreate() {
        super.onCreate()

        val sdcardDirName = Environment.getExternalStorageDirectory().absolutePath

        val fileName = AppGlobals.getApplication()
            .getString(R.string.app_name) + BuildConfig.VERSION_CODE.toString() + ".apk"

        filePath = "$sdcardDirName/$fileName"

        mProgressBar = findViewById(R.id.mProgressBar)
        upDataNow = findViewById(R.id.upDataNow)
        upDataNow.setOnClickListener {

            if (Build.VERSION.SDK_INT>=26){
                val hasInstallPermission = isHasInstallPermissionWithO(context)
                if (!hasInstallPermission) {
                    startInstallPermissionSettingActivity(context)
                }else{
                    startDownLoad()
                }
            }else{

                startDownLoad()
            }



        }
    }

    private fun startDownLoad() {
        if (!isDownloading) {
            isDownloading = true
            toDownLoad()
            upDataNow.text = "正在更新中"
            mProgressBar.visibility = VISIBLE
            popupInfo.isDismissOnTouchOutside = false
            popupInfo.isDismissOnBackPressed = false
        }
    }


    private fun toDownLoad() {



        PermissionX.init(target)
            .permissions(*permissions)
            .onExplainRequestReason { scope, deniedList ->
                val msg = "获取内部存储"
                val positive = "确定"
                val negative = "取消"
                scope.showRequestReasonDialog(deniedList, msg, positive, negative)
            }.onForwardToSettings { scope, deniedList ->
                val msg = "获取内部存储"
                val positive = "确定"
                val negative = "取消"
                scope.showForwardToSettingsDialog(deniedList, msg, positive, negative)
            }.request { allGranted, _, deniedList ->
                if (!allGranted || deniedList.isNotEmpty()) {
                    dismiss()
                } else {
                    onDownloading()
                }

            }

    }

    /**
     * 开启设置安装未知来源应用权限界面
     * @param context
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private fun startInstallPermissionSettingActivity(context: Context?) {
        if (context == null) {
            return
        }
        val intent = Intent()
        //获取当前apk包URI，并设置到intent中（这一步设置，可让“未知应用权限设置界面”只显示当前应用的设置项）
        val packageURI = Uri.parse("package:" + context.packageName)
        intent.data = packageURI
        //设置不同版本跳转未知应用的动作
        if (Build.VERSION.SDK_INT >= 26) {
            //intent = new Intent(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,packageURI);
            intent.action = Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES
        } else {
            intent.action = Settings.ACTION_SECURITY_SETTINGS
        }
        (context as Activity).startActivity(intent)
        Toast.makeText(context, "请打开未知应用安装权限", Toast.LENGTH_SHORT).show()
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private fun isHasInstallPermissionWithO(context: Context?): Boolean {
        return context?.packageManager?.canRequestPackageInstalls() ?: false
    }
    private fun onDownloading() {

        checkLocalFilePath(filePath)

        val cache: Cache? = buildCache()
        okHttpClient = OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS) //链接超时
            .retryOnConnectionFailure(false) //设置出现错误进行重新连接。
            .connectTimeout(30, TimeUnit.SECONDS)
            .cache(cache)
            .readTimeout(60, TimeUnit.SECONDS)
            .build()

        val cc = CacheControl.Builder()
            .noStore()
            .noCache()
            .build()

        val request: Request = Request.Builder()
            .url(mVersionBean?.version?.downloadUrl ?: "")
            .cacheControl(cc)
            .get()
            .build()

        okHttpClient?.newCall(request)
            ?.enqueue(object : Callback {
                override fun onFailure(call: Call, e: IOException) {
                    downFailed()

                }

                override fun onResponse(call: Call, response: Response) {
                    val responseBody = response.body

                    var stream: InputStream? = null //输入流

                    var fos: FileOutputStream? = null //输出流

                    try {
                        stream = responseBody?.byteStream() //获取输入流
                        val total = responseBody?.contentLength() //获取文件大小
                        setMax(total) //为progressDialog设置大小
                        if (stream != null) {

                            val file =
                                File(filePath) // 设置路径
                            fos = FileOutputStream(file)
                            val buf = ByteArray(1024)
                            var ch = -1
                            var process = 0
                            while (stream.read(buf).also { ch = it } != -1) {
                                fos.write(buf, 0, ch)
                                process += ch
                                downLoading(process) //这里就是关键的实时更新进度了！
                            }
                        }
                        fos?.flush()
                        // 下载完成
                        fos?.close()
                        downSuccess()
                    } catch (e: Exception) {
                        e.printStackTrace()
                        downFailed()

                    } finally {
                        try {
                            stream?.close()
                        } catch (e: IOException) {
                            e.printStackTrace()
                        }
                        try {
                            fos?.close()
                        } catch (e: IOException) {
                            e.printStackTrace()
                        }
                    }

                }
            })
    }

    private fun setMax(total: Long?) {
        handles.post {
            mProgressBar.visibility = VISIBLE
            mProgressBar.max = total?.toInt() ?: 0
        }

    }

    private fun downLoading(process: Int) {
        handles.post {
            mProgressBar.visibility = VISIBLE
            mProgressBar.progress = process
            if(mProgressBar.progress>=mProgressBar.max){
                downSuccess()
            }
        }
    }

    private fun downSuccess() {
        AppGlobals.getApplication().startActivity(getInstallApkIntent())
    }

    /**
     * 下载完成，安装
     */
    private fun getInstallApkIntent(): Intent? {
        val installIntent = Intent(Intent.ACTION_VIEW)
        val mContext: Context = AppGlobals.getApplication()
        val apkFile = File(filePath)
        val formFileUri: Uri = FileProviderHelper.getFormFileUri(mContext, apkFile)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        }
        //
        installIntent.setDataAndType(formFileUri, "application/vnd.android.package-archive")
        installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        return installIntent
    }


    private fun downFailed() {

        handles.post {
            if (isDownloading) {
                isDownloading = false
            }
            MyApp.isAppUpData=false
            mProgressBar.visibility = GONE
            upDataNow.text = "下载失败,重新下载"
            mProgressBar.visibility = VISIBLE
            popupInfo.isDismissOnTouchOutside = true
            popupInfo.isDismissOnBackPressed = true
        }

    }


    /**
     * 用来检查文件路径是否已经存在
     *
     * @param path
     */
    private fun checkLocalFilePath(path: String) {

        val file = File(path)
        val dir = file.parentFile
        if (!dir.exists()) {
            val mkdir = dir.mkdir()
            if (mkdir) {
                if (!file.exists()) {
                    try {
                        file.createNewFile()
                        file.setWritable(true)
                        file.setReadable(true)
                    } catch (e: java.lang.Exception) {
                        e.printStackTrace()
                    }
                } else {
                    file.delete()
                }
            }
        }
    }

    private fun buildCache(): Cache? {
        var cache: Cache? = null
        try {
            val cacheFile: File = FileUtil.createDir("okHttpClient")

            if (cacheFile != null && cacheFile.exists()) {
                val cacheSize = 1000 * 1024 * 1024
                cache = Cache(cacheFile, cacheSize.toLong())
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return cache
    }

}